package com.ztgf.order.service;

import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.baomidou.mybatisplus.mapper.Wrapper;
import com.baomidou.mybatisplus.plugins.Page;
import com.baomidou.mybatisplus.service.impl.ServiceImpl;
import com.ztgf.common.constant.Result;
import com.ztgf.common.enums.CodeEnum;
import com.ztgf.order.common.config.YmlConfig;
import com.ztgf.order.mapper.OrderInvoiceMapper;
import com.ztgf.order.models.bo.*;
import com.ztgf.order.models.dto.OrderInfoDTO;
import com.ztgf.order.models.dto.OrderInvoiceDTO;
import com.ztgf.order.models.dto.OrderStatusDTO;
import com.ztgf.order.models.service.IOrderInfoService;
import com.ztgf.order.models.service.IOrderInvoiceService;
import com.ztgf.order.models.service.IOrderStatusService;
import com.ztgf.order.models.vo.OrderInfoVO;
import com.ztgf.order.models.vo.OrderInvoiceDetailsVO;
import com.ztgf.order.models.vo.OrderInvoiceVO;
import com.ztgf.shopping.models.dto.shop.ShopInvoiceHeadDTO;
import com.ztgf.shopping.models.service.shop.IShopInvoiceHeadService;
import com.ztgf.sms.models.bo.EmailSendBO;
import com.ztgf.sms.models.service.IEmailInfoService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.StringUtils;
import org.apache.dubbo.config.annotation.DubboReference;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Lazy;
import org.springframework.scheduling.annotation.Async;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * 订单发票管理控制器
 *
 * @author chenyu.wang
 * @Date 2020-06-03 15:58:16
 */
@Slf4j
@DubboService
@Lazy
public class OrderInvoiceServiceImpl extends ServiceImpl<OrderInvoiceMapper, OrderInvoiceDTO> implements IOrderInvoiceService {

    @Resource
    private YmlConfig ymlConfig;
    @DubboReference
    private IShopInvoiceHeadService shopInvoiceHeadService;
    @Autowired
    private IOrderStatusService orderStatusService;
    @DubboReference
    private IEmailInfoService emailInfoService;


    /**
     * 下单添加发票抬头信息
     *
     * @param orderInfoVO
     * @param invoiceHeadId
     * @param orderInvoiceBO
     * @return
     */
    public boolean addByOrderInfo(OrderInfoVO orderInfoVO, Long invoiceHeadId, OrderInvoiceBO orderInvoiceBO) {
        OrderInvoiceSaveBO orderInvoiceSaveBO = new OrderInvoiceSaveBO();
        orderInvoiceSaveBO.setShopId(orderInfoVO.getSellShopId());
        orderInvoiceSaveBO.setReceiveShopId(orderInfoVO.getBuyerShopId());
        orderInvoiceSaveBO.setOrderId(orderInfoVO.getId());
        orderInvoiceSaveBO.setInvoicePrice(orderInfoVO.getActualMoney());
        if (null == invoiceHeadId) {
            return add(orderInvoiceSaveBO);
        }
        BeanUtils.copyProperties(orderInvoiceBO, orderInvoiceSaveBO);
        ShopInvoiceHeadDTO shopInvoiceHeadDTO = shopInvoiceHeadService.selectById(invoiceHeadId);
        orderInvoiceSaveBO.setName(shopInvoiceHeadDTO.getName());
        orderInvoiceSaveBO.setTaxpayerId(shopInvoiceHeadDTO.getTaxpayerId());
        orderInvoiceSaveBO.setMobile(orderInvoiceBO.getMobile());
        orderInvoiceSaveBO.setInvoiceContent(orderInvoiceBO.getInvoiceContent());
        orderInvoiceSaveBO.setType(orderInvoiceBO.getType());
        orderInvoiceSaveBO.setPostalCode(orderInvoiceBO.getPostalCode());
        orderInvoiceSaveBO.setAreaId(orderInvoiceBO.getAreaId());
        orderInvoiceSaveBO.setReceivingName(orderInvoiceBO.getReceivingName());
        orderInvoiceSaveBO.setShopInvoiceId(invoiceHeadId);
        orderInvoiceSaveBO.setReceivingAddress(orderInvoiceBO.getReceivingAddress());
        if (orderInvoiceBO.getType() == 0) {
            orderInvoiceSaveBO.setInvoiceType(1);
        } else {
            orderInvoiceSaveBO.setInvoiceType(0);
        }
        return add(orderInvoiceSaveBO);
    }

    @Override
    public boolean updateOrderInvoiceById(OrderInvoiceDetailsVO vo) {
        OrderInvoiceDTO orderInvoiceDTO = new OrderInvoiceDTO();
        if (vo.getType()==0){
            orderInvoiceDTO.setType(vo.getType());
            orderInvoiceDTO.setId(vo.getId());
            orderInvoiceDTO.setCompanyName(vo.getCompanyName());
            orderInvoiceDTO.setInvoiceCode(vo.getInvoiceCode());
            orderInvoiceDTO.setInvoiceNumber(vo.getInvoiceNumber());
            orderInvoiceDTO.setInvoiceUrl(vo.getInvoiceUrl());
            orderInvoiceDTO.setLogisticsType(vo.getLogisticsType());
            orderInvoiceDTO.setNumberPhone(vo.getNumberPhone());
            orderInvoiceDTO.setReceivingAddress(vo.getReceiveAddress());
            orderInvoiceDTO.setReceivingName(vo.getReceiveName());
            orderInvoiceDTO.setMobile(vo.getReceivePhone());
            orderInvoiceDTO.setInvoiceType(1);
        }else{
            orderInvoiceDTO.setType(vo.getType());
            orderInvoiceDTO.setId(vo.getId());
            orderInvoiceDTO.setInvoiceType(0);
            orderInvoiceDTO.setEmail(vo.getReceiveEmail());
            orderInvoiceDTO.setInvoiceCode(vo.getInvoiceCode());
            orderInvoiceDTO.setInvoiceNumber(vo.getInvoiceNumber());
            orderInvoiceDTO.setInvoiceUrl(vo.getInvoiceUrl());
        }
        orderInvoiceDTO.setAreaId(vo.getAreaId());
        boolean flag= this.updateById(orderInvoiceDTO);

        if (flag){
            OrderInvoiceDTO orderInvoiceDTO1 = this.selectById(vo.getId());
            if (orderInvoiceDTO1.getType() == 1){
                this.sendEmail(orderInvoiceDTO1.getShopId (), orderInvoiceDTO1.getEmail(), orderInvoiceDTO1.getInvoiceUrl());
            }
        } else {
            return false;
        }
        return true;
    }

    @Override
    public Result updateLogistics(LogisticsEditBO saveBO) {
        OrderInvoiceDTO dto = new OrderInvoiceDTO();
        dto.setLogisticsType(saveBO.getType());
        dto.setCompanyName(saveBO.getCompanyName());
        dto.setNumberPhone(saveBO.getMailNo());
        dto.setId(saveBO.getId());
        if(updateById(dto)){
            return new Result();
        } else {
            return new Result(CodeEnum.FAIL_100011);
        }
    }

    /**
     * 开发票更新内容
     *
     * @param orderOpenInvoiceBO
     * @return
     */
    @Override
    public boolean updateByOrderInfo(OrderOpenInvoiceBO orderOpenInvoiceBO) {
        Long invoiceHeadId = orderOpenInvoiceBO.getInvoiceHeadId();//发票抬头id
        Long orderId = orderOpenInvoiceBO.getOrderId();//订单id
        OrderInvoiceBO orderInvoiceBO = orderOpenInvoiceBO.getOrderInvoiceBO();
        ShopInvoiceHeadDTO shopInvoiceHeadDTO = shopInvoiceHeadService.selectById(invoiceHeadId);
        OrderStatusDTO orderStatusDTO = orderStatusService.getByOrderId(orderId);
        orderStatusDTO.setInvoiceState(1);//更改发票状态未申请中
        boolean b = orderStatusService.updateById(orderStatusDTO);//更新发票状态
        if (b) {
            OrderInvoiceDTO orderInvoiceDTO = getByOrderId(orderId);
            orderInvoiceDTO.setName(shopInvoiceHeadDTO.getName());
            orderInvoiceDTO.setTaxpayerId(shopInvoiceHeadDTO.getTaxpayerId());
            orderInvoiceDTO.setMobile(orderInvoiceBO.getMobile());
            orderInvoiceDTO.setInvoiceContent(orderInvoiceBO.getInvoiceContent());
            orderInvoiceDTO.setType(orderInvoiceBO.getType());
            orderInvoiceDTO.setPostalCode(orderInvoiceBO.getPostalCode());
            orderInvoiceDTO.setAreaId(orderInvoiceBO.getAreaId());
            orderInvoiceDTO.setReceivingName(orderInvoiceBO.getReceivingName());
            orderInvoiceDTO.setEmail(orderInvoiceBO.getEmail());
            orderInvoiceDTO.setShopInvoiceId(invoiceHeadId);
            orderInvoiceDTO.setReceivingAddress(orderInvoiceBO.getReceivingAddress());
            if (orderInvoiceBO.getType().equals(0)) {
                orderInvoiceDTO.setInvoiceType(1);
            } else {
                orderInvoiceDTO.setInvoiceType(0);
            }
            return updateById(orderInvoiceDTO);
        }
        return false;
    }

    @Override
    public boolean add(OrderInvoiceSaveBO saveBO) {
        OrderInvoiceDTO dto = new OrderInvoiceDTO();
        BeanUtils.copyProperties(saveBO, dto);
        Long id = ymlConfig.getPkId();
        dto.setId(id);
        return this.insert(dto);
    }

    @Override
    public Page<OrderInvoiceVO> queryMyOderInvocie(OrderMyInvocieBO bo) {
        Page<OrderInvoiceVO> page = new Page<>(bo.getPageNo(), bo.getPageSize());
        List<OrderInvoiceVO> list = baseMapper.queryMyOderInvocie(page, bo);
        if (list!=null && list.size()>0){
            Iterator<OrderInvoiceVO> it = list.iterator();
            while(it.hasNext()){
                OrderInvoiceVO orderInvoiceVO = it.next();
                if (orderInvoiceVO.getOrderState()==6 || orderInvoiceVO.getOrderState()==7){
                    orderInvoiceVO.setOrderState(0);
                }else {
                    orderInvoiceVO.setOrderState(1);
                }
            }
        }
        page.setRecords(list);
        return page;
    }

    @Override
    public OrderInvoiceDTO getOrderInvoiceByOrderId(Long orderId, Long shopId) {
        Wrapper<OrderInvoiceDTO> wrapper = new EntityWrapper<>();
        wrapper.eq("order_id", orderId);
        wrapper.eq("receive_shop_id", shopId);
        return this.selectOne(wrapper);
    }

    @Override
    public OrderInvoiceDTO getByOrderId(Long orderId) {
        Wrapper<OrderInvoiceDTO> wrapper = new EntityWrapper<>();
        wrapper.eq("order_id", orderId);
        return selectOne(wrapper);
    }


    /*
     * @description:卖家个人中心发票列表去开票
     * @author: chenyu.wang
     * @date: 2020-08-18
     * @param:
     * @return:
     */
    @Override
    public boolean updateOpenInvoice(OrderOpenUpInvoiceBO bo) {
        OrderInvoiceDTO dto = this.getByOrderId(bo.getOrderId());
        log.info("开票信息 : {}", bo);
        if (dto == null) {
            return false;
        }
        OrderInvoiceDTO updateDto = new OrderInvoiceDTO();
        updateDto.setId(dto.getId());
        updateDto.setUpdateUserId(bo.getSellerShopId());
        updateDto.setType(bo.getType());//发票类型
        if (StringUtils.isNotBlank(bo.getInvoiceFile())) {
            updateDto.setInvoiceUrl(bo.getInvoiceFile());//发票图片地址
        }
        if (StringUtils.isNotBlank(bo.getInvoiceCode())) {
            updateDto.setInvoiceCode(bo.getInvoiceCode());//发票代码
        }
        if (StringUtils.isNotBlank(bo.getInvoiceNumber())) {
            updateDto.setInvoiceNumber(bo.getInvoiceNumber());//发票编号
        }
        if (bo.getLogisticsType() != null) {
            updateDto.setLogisticsType(bo.getLogisticsType());//物流类型,0选择物流,1自己联系物流
        }
        if (StringUtils.isNotBlank(bo.getCompanyNameOrDeliveryName())) {
            updateDto.setCompanyName(bo.getCompanyNameOrDeliveryName());//物流公司名称/送货员姓名
        }
        if (StringUtils.isNotBlank(bo.getNumberOrDeliveryPhone())) {
            updateDto.setNumberPhone(bo.getNumberOrDeliveryPhone());//物流单号/送货员联系电话
        }
        if (StringUtils.isNotBlank(bo.getReceivingAddress())) {
            updateDto.setReceivingAddress(bo.getReceivingAddress());//收票地址
        }
        if (bo.getType().equals(0)) {
            updateDto.setInvoiceType(1);
        } else {
            updateDto.setInvoiceType(0);
        }
        boolean b = this.updateById(updateDto);
        if (!b) {
            return false;
        }

        //修改订单发票状态
        orderStatusService.updateOrderInvoiceState(dto.getOrderId());
        //如果为电子发票的时候需要发送邮件信息
        if (StringUtils.isNotBlank(dto.getEmail()) && StringUtils.isNotBlank(bo.getInvoiceFile())) {
            this.sendEmail(dto.getReceiveShopId(), dto.getEmail(), bo.getInvoiceFile());
        }
        return true;
    }

    /*
     * @description:根据id查询订单发票详情
     * @author: chenyu.wang
     * @date: 2020-08-18
     * @param:
     * @return:
     */
    @Override
    public OrderInvoiceDetailsVO queryById(Long id) {
        return baseMapper.queryById(id);
    }

    /*
     * @description:发送发票信息邮件
     * @author: chenyu.wang
     * @date: 2020-09-25
     * @return:
     */
    @Async
    public void sendEmail(Long shopId, String email, String file) {
        EmailSendBO emailBO = new EmailSendBO();
        emailBO.setShopId(shopId);
        emailBO.setEmail(email);
        emailBO.setType(0);
        emailBO.setContext(file);
        emailInfoService.sendInvoiceEmail(emailBO);
    }
}
